//
//  NSArray+NullSafe.m
//  Express
//
//  Created by lhongl on 2025/9/26.
//  Copyright © 2025 QM. All rights reserved.
//

#import "NSArray+NullSafe.h"
#import "NSObject+Swizzling.h"
@implementation NSArray (NullSafe)

#ifdef DEBUG

#else
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSArrayI");

        [class mg_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(mg_objectAtIndex:)];

        [class mg_swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(mg_objectAtIndexedSubscript:)];

        Class arrayClass = NSClassFromString(@"__NSPlaceholderArray");
        [arrayClass mg_swizzleMethod:@selector(initWithObjects:count:) withMethod:@selector(mg_initWithObjects:count:)];

    });
}
#endif

- (instancetype)mg_initWithObjects:(id  _Nonnull const [])objects count:(NSUInteger)cnt {
    id safeObjects [cnt];
    NSUInteger j = 0;
    for (NSUInteger i=0; i<cnt; i++) {
        id obj = objects[i];
        if (!obj) {
            continue;
        }
        safeObjects[j] = obj;
        j++;
    }
    cnt = j;
    return [self mg_initWithObjects:safeObjects count:cnt];
}

- (id)mg_objectAtIndex:(NSUInteger)index{
    if (index < self.count) {
        return [self mg_objectAtIndex:index];
    }else{
        return nil;
    }
}
- (id)mg_objectAtIndexedSubscript:(NSUInteger)idx{
    if (idx < self.count) {
        return [self mg_objectAtIndexedSubscript:idx];
    }else{
        return nil;
    }
}

@end

@implementation NSMutableArray (NullSafe)

#ifdef DEBUG

#else
+ (void)load {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = NSClassFromString(@"__NSArrayM");
        [class mg_swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(mg_objectAtIndex:)];
        [class mg_swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(mg_objectAtIndexedSubscript:)];

        [class mg_swizzleMethod:@selector(insertObject:atIndex:) withMethod:@selector(da_insertObject:atIndex:)];
        [class mg_swizzleMethod:@selector(setObject:atIndexedSubscript:) withMethod:@selector(da_setObject:atIndexedSubscript:)];

        [class mg_swizzleMethod:@selector(removeObjectsInRange:) withMethod:@selector(mg_removeObjectsInRange:)];

        [class mg_swizzleMethod:@selector(replaceObjectAtIndex:withObject:) withMethod:@selector(mg_replaceObjectAtIndex:withObject:)];

    });
}
#endif

- (id)mg_objectAtIndex:(NSUInteger)index{
    if (index < self.count) {
        return [self mg_objectAtIndex:index];
    }else{
        return nil;
    }
}
- (id)mg_objectAtIndexedSubscript:(NSUInteger)idx{
    if (idx < self.count) {
        return [self mg_objectAtIndexedSubscript:idx];
    }else{
        return nil;
    }
}


- (void)da_insertObject:(id)anObject atIndex:(NSUInteger)index {
    if (index > self.count) {
        return;
    }
    if (!anObject) {
        return;
    }

    [self da_insertObject:anObject atIndex:index];
}

- (void)da_setObject:(id)obj atIndexedSubscript:(NSUInteger)idx {
    if (idx > self.count) {
        return;
    }
    if (!obj) {
        return;
    }

    [self da_setObject:obj atIndexedSubscript:idx];
}

- (void)mg_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
    if (index > self.count) {
        return;
    }
    if (!anObject) {
        return;
    }

    [self mg_replaceObjectAtIndex:index withObject:anObject];
}


- (void)mg_removeObjectsInRange:(NSRange)range{
    if (range.location > self.count) {
        return;
    }
    [self mg_removeObjectsInRange:range];
}


@end
